﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using AnalisisDeRiesgos.Dal;

namespace AnalisisDeRiesgos.Models.Danger
{
    public class EditDangerModel
    {
        #region Properties
        public int DangerId { get; set; }

        [DisplayName("Jefatura/Gerencia")]
        [Required(ErrorMessage = "La Jefatura/Gerencia es requerida")]
        public int Management { get; set; }

        [DisplayName("Proceso")]
        [Required(ErrorMessage = "El Proceso es requerido")]
        public int Process { get; set; }

        [DisplayName("Area")]
        [Required(ErrorMessage = "El Area es requerido")]
        public int Area { get; set; }

        [DisplayName("Actividad")]
        [Required(ErrorMessage = "La Actividad es requerida")]
        public int Activity { get; set; }

        [DisplayName("Descripcion del peligro")]
        [Required(ErrorMessage = "Una descripcion breve del peligro es necesario")]
        [StringLength(150, ErrorMessage = "La descripcion del peligro debe ser máximo de 150 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ\n]+$", ErrorMessage = "La descripcion debe ser solo letras o números")]
        public string Danger { get; set; }

        [DisplayName("Riesgo")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        public int Risk { get; set; }

        [DisplayName("Normal/Anormal")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        public char OperativeCondition { get; set; }

        [DisplayName("Humano/Infraestructura")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        public char AffectedTarget { get; set; }

        [DisplayName("Ubicacion especifica")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(50, ErrorMessage = "La ubicacion especifica debe contener como maximo 50 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ\n]+$", ErrorMessage = "La ubicacion especifica debe ser solo letras o números")]
        public string EspecificUbication { get; set; }

        [DisplayName("Causa que originan el peligro")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(100, ErrorMessage = "La causa debe contener como maximo 100 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ\n]+$", ErrorMessage = "La causa debe ser solo letras o números")]
        public string Causes { get; set; }

        [DisplayName("Posibles consecuencias")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(100, ErrorMessage = "La consecuencia debe contener como maximo 100 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ\n]+$", ErrorMessage = "La consecuencia debe ser solo letras o números")]
        public string Consecuences { get; set; }

        [DisplayName("Controles existentes")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(150, ErrorMessage = "Las controles existentes debe contener como maximo 150 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ\n]+$", ErrorMessage = "Los controles debe ser solo letras o números")]
        public string ExistingControls { get; set; }

        [DisplayName("Frecuencia")]
        public int Frequence { get; set; }

        [DisplayName("Numero de expuestos")]
        public int ExposedNumber { get; set; }

        [DisplayName("Controles")]
        public int Controls { get; set; }

        [DisplayName("Severidad")]
        public int Severity { get; set; }

        [DisplayName("Posibles controles")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(150, ErrorMessage = "Las posibles controles debe contener como maximo 150 caracteres")]
        [RegularExpression(@"^[a-zA-Z0-9 \(\)ñÑ\-.,áéíóúÁÉÍÓÚ]+$", ErrorMessage = "Los controles debe ser solo letras o números")]
        public string PosibleControls { get; set; }       

        [DisplayName("Plazo de expiracion para las actividades")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        public string ExpirationDate { get; set; }

        [DisplayName("Estado")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(3, ErrorMessage = "El porcentaje como maximo tiene 3 cifras")]
        [RegularExpression(@"^[0-9.,]+$", ErrorMessage = "El porcentaje solo debe ser numeros")]
        public string Status { get; set; }

        [DisplayName("Factor K")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(11, ErrorMessage = "El Factor K debe tener como maximo 11 cifras")]
        [RegularExpression(@"^[0-9]+$", ErrorMessage = "El factor k solo debe ser numeros")]
        public string KFactor { get; set; }

        [DisplayName("Inversion en Bs.")]
        [RegularExpression(@"^[0-9.,]+$", ErrorMessage = "La inversion solo debe ser numeros")]
        [StringLength(20, ErrorMessage = "La inversion debe ser maximo con 20 cifras")]
        public string Inversion { get; set; }
        #endregion

        #region DropdownLists
        public IEnumerable<SelectListItem> Managements
        {
            get
            {
                return managementList;
            }
        }

        public IEnumerable<SelectListItem> Processes
        {
            get
            {
                return processList;
            }
        }

        public IEnumerable<SelectListItem> Areas
        {
            get
            {
                return areaList;
            }
        }

        public IEnumerable<SelectListItem> Activitys
        {
            get
            {
                return activityList;
            }
        }

        public IEnumerable<SelectListItem> Frequences
        {
            get
            {
                return frequencyList;
            }
        }

        public IEnumerable<SelectListItem> Affecteds
        {
            get
            {
                return affectedList;
            }
        }

        public IEnumerable<SelectListItem> ControlList
        {
            get
            {
                return controlsList;
            }
        }

        public IEnumerable<SelectListItem> SeverityList
        {
            get
            {
                return severityList;
            }
        }

        public IEnumerable<SelectListItem> KValuesList
        {
            get
            {
                return theKValuesList;
            }
        }

        private List<SelectListItem> managementList;
        private List<SelectListItem> processList;
        private List<SelectListItem> areaList;
        private List<SelectListItem> activityList;
        private List<SelectListItem> frequencyList;
        private List<SelectListItem> affectedList;
        private List<SelectListItem> controlsList;
        private List<SelectListItem> severityList;
        private List<SelectListItem> theKValuesList;
        #endregion

        riskanalysisEntities entities = new riskanalysisEntities();

        public EditDangerModel(){
            FillList();
        }

        public EditDangerModel(int dangerId)
        {
            FillDangerById(dangerId);
        }        

        private void FillList()
        {
            managementList = new List<SelectListItem>();

            var queryManagements = from m in entities.managements
                                   where m.enabled
                                   select m;

            foreach (management item in queryManagements)
            {
                managementList.Add(
                    new SelectListItem
                    {
                        Text = item.name,
                        Value = item.managementId.ToString()
                    });
            }
            processList = Utils.FillProcessList(Management);
            areaList = Utils.FillAreaList(Process);
            activityList = Utils.FillActivityList(Area);
            frequencyList = Utils.GetFrequencyList();
            affectedList = Utils.GetAffectedList();
            controlsList = Utils.GetControlExistenceList();
            severityList = Utils.GetSeverityList();
            theKValuesList = Utils.GetKValuesList();
        }

        private void FillDangerById(int dangerId)
        {
            danger theDanger = GetDangerById(dangerId);

            DangerId = theDanger.dangerId;
            Management = theDanger.activity.area.process.management.managementId;
            Process = theDanger.activity.area.process.processId;
            Area = theDanger.activity.area.areaId;
            Activity = theDanger.activityId;
            Causes = theDanger.causes;
            Consecuences = theDanger.consecuences;
            Controls = theDanger.controlExistence;
            Danger = theDanger.description;
            EspecificUbication = theDanger.ubication;
            ExistingControls = theDanger.controls;
            ExpirationDate = theDanger.expirationDate.ToString("d", Utils.culture);
            ExposedNumber = theDanger.exposed;
            Frequence = theDanger.frecuence;
            KFactor = theDanger.kFactor.ToString();
            OperativeCondition = Convert.ToChar(theDanger.operativeCondition);
            PosibleControls = theDanger.posibleControls;
            Risk = theDanger.riskId;
            Severity = theDanger.severity;
            Status = theDanger.status.ToString();
            AffectedTarget = Convert.ToChar(theDanger.affectedTarget);
            Inversion = theDanger.inversion.ToString();
            FillList();
        }

        public static danger GetDangerById(int id)
        {
            riskanalysisEntities entities = new riskanalysisEntities();
            var query = from d in entities.dangers
                        where d.dangerId == id
                        select d;

            danger theDanger = query.FirstOrDefault();

            if (theDanger == null)
                throw new EditDangerException("El peligro que usted busca no existe!");
            return theDanger;
        }

        private danger GetDangerByIdForUpdate(int id)
        {            
            var query = from d in entities.dangers
                        where d.dangerId == id
                        select d;

            danger theDanger = query.FirstOrDefault();

            if (theDanger == null)
                throw new EditDangerException("El peligro que usted busca no existe!");
            return theDanger;
        }

        public void Save()
        {
            danger theDanger = GetDangerByIdForUpdate(DangerId);


            theDanger.dangerId = DangerId;
            theDanger.activityId = Activity;
            theDanger.causes = Causes;
            theDanger.consecuences = Consecuences;
            theDanger.controlExistence = Controls;
            theDanger.description = Danger;
            theDanger.ubication = EspecificUbication;
            theDanger.controls = ExistingControls;
            theDanger.expirationDate = Convert.ToDateTime(ExpirationDate, Utils.culture);
            theDanger.exposed = ExposedNumber;
            theDanger.frecuence = Frequence;
            theDanger.kFactor = Convert.ToInt32(KFactor);
            theDanger.operativeCondition = OperativeCondition.ToString();
            theDanger.posibleControls = PosibleControls;
            theDanger.riskId = Risk;
            theDanger.severity = Severity;
            theDanger.status = Convert.ToInt32(Status);
            theDanger.affectedTarget = AffectedTarget.ToString();
            theDanger.inversion = Convert.ToDouble(Inversion);

            entities.SaveChanges();
        }
    }
}